package com.hfzy.ihk.web.websocket.support.toBrowser.handler;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.hfzy.ihk.common.util.ValidateUtils;
import com.hfzy.ihk.common.util.date.DateUtils;
import com.hfzy.ihk.common.util.string.StringUtil;
import com.hfzy.ihk.common.util.uuid.base64uuid.UUIDs;
import com.hfzy.ihk.facade.aliyuncall.service.AliyunCallService;
import com.hfzy.ihk.facade.ivr.service.FreeswitchAsrCallService;
import com.hfzy.ihk.web.websocket.conf.PublicConfig;
import com.hfzy.ihk.web.websocket.constant.Constants;
import com.hfzy.ihk.web.websocket.constant.RedisFields;
import com.hfzy.ihk.web.websocket.support.SampleCache;
import com.hfzy.ihk.web.websocket.support.WebSocketManager;
import com.hfzy.ihk.web.websocket.support.base.WebSocketMessageHandler;
import com.hfzy.ihk.web.websocket.utils.SpringWebSocketUtils;
import com.hfzy.ihk.facade.freeswitchCall.service.FreeswitchCallService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2016/12/1.
 *
 * @author wws
 */
@Component
public class BrowserWebSocketMessageHandler implements WebSocketMessageHandler {

    private static final Logger logger = LoggerFactory.getLogger(BrowserWebSocketMessageHandler.class);

    @Reference(version = "1.0.0")
    AliyunCallService aliyunCallService;

    @Reference(version = "1.0.0")
    FreeswitchCallService freeswitchCallService;

    @Reference(version = "1.0.0")
    FreeswitchAsrCallService freeswitchAsrCallService;

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
        Map<String,String> validateMap = null;
        Map<String, String> map  = null;

        String sessionId = null;
        String mainCallPhone = null;
        String targetCallPhone = null;
        String token = null;
        String userId = null;
        String userNo = null;
        String dataId = null; //置业oracle通话记录的id
        String whereFrom = null;
        String pageFrom = null;
        String mainCallType = null;
        String commitTo = null;
        String city = null;
        String customerName = null;
        String showNum = null;

        String project = null;
        String propertyNo = null;
        String objectId = null;//置业oracle通话记录中，盘源、客户、项目的id（联动call）
        String callTaskId = null;
        String packageId = null;
        String packageName=null;
        String source = null;
        String actionCodeBreak = null; //开场白是否能打断 1,0
        String voiceCode = null; //开场白语音文件id
        String voiceText = null;//开场白话术文本
        String company = null;

        //是否需要启动ASR
        boolean needAsr = false;

        try {
            JSONObject json = JSONObject.parseObject(message.getPayload().toString());

            String msgType = json.get("msgType").toString();

            switch (msgType){

                case "asrCall": //智能外呼消息
                    logger.info("received message:{}",message.getPayload().toString());
                    sessionId       = json.get(RedisFields.CALL_HISTORY_SESSION_ID)       == null?null:json.get(RedisFields.CALL_HISTORY_SESSION_ID).toString(); //
                    mainCallPhone   = json.get(RedisFields.CALL_HISTORY_MAIN_CALL_PHONE)   == null?null:json.get(RedisFields.CALL_HISTORY_MAIN_CALL_PHONE).toString().trim(); //主叫；由拨号时发送过来
                    token           = json.get(RedisFields.CALL_HISTORY_MACHINE_FROM)      == null?null:json.get(RedisFields.CALL_HISTORY_MACHINE_FROM).toString();//机器码：用于定位websocket对象（websocket）
                    userId          = json.get(RedisFields.CREATE_USER_ID)                 == null?null:json.get(RedisFields.CREATE_USER_ID).toString();
                    dataId          = json.get(RedisFields.CALL_HISTORY_DATA_ID)           == null?null:json.get(RedisFields.CALL_HISTORY_DATA_ID).toString(); //置业或app数据库 数据id，用于jms推送数据时，置业或app更新数据的索引；这要求置业或app保存数据成功后再提交呼叫任务到云呼
                    whereFrom       = json.get(RedisFields.CALL_HISTORY_WHERE_FROM)        == null?null:json.get(RedisFields.CALL_HISTORY_WHERE_FROM).toString(); //来源：app(0),置业(1)
                    pageFrom        = json.get(RedisFields.CALL_HISTORY_PAGE_FROM)         == null?null:json.get(RedisFields.CALL_HISTORY_PAGE_FROM).toString(); //app盘源(0),app联动call(1),置业盘源(2)，置业联动call(3)? （websocket）
                    mainCallType    = json.get(RedisFields.CALL_HISTORY_MAIN_CALL_TYPE)    == null?null:json.get(RedisFields.CALL_HISTORY_MAIN_CALL_TYPE).toString(); //主叫号码是什么号码
                    commitTo        = json.get(RedisFields.CALL_HISTORY_COMMIT_TO)         == null?null:json.get(RedisFields.CALL_HISTORY_COMMIT_TO).toString(); //提交到哪里：东进(0)/电信(1)/手机(2)
                    city            = json.get(RedisFields.CALL_HISTORY_CITY)              == null?null:json.get(RedisFields.CALL_HISTORY_CITY).toString();   //经纪所在的城市
                    customerName    = json.get(RedisFields.CALL_HISTORY_CUSTOMER_NAME)     == null?null:json.get(RedisFields.CALL_HISTORY_CUSTOMER_NAME).toString(); //
                    showNum         = json.get(RedisFields.CALL_HISTORY_SHOW_NUM)          == null?null:json.get(RedisFields.CALL_HISTORY_SHOW_NUM).toString(); //
                    project         = json.get(RedisFields.CALL_HISTORY_PROJECT)           == null?null:json.get(RedisFields.CALL_HISTORY_PROJECT).toString(); //
                    propertyNo      = json.get(RedisFields.CALL_HISTORY_PROPERTY_NO)       == null?null:json.get(RedisFields.CALL_HISTORY_PROPERTY_NO).toString(); //
                    objectId        = json.get(RedisFields.CALL_HISTORY_OBJECT_ID)         == null?null:json.get(RedisFields.CALL_HISTORY_OBJECT_ID).toString(); //
                    callTaskId        = json.get(RedisFields.CALL_HISTORY_CALL_TASK_ID)         == null?null:json.get(RedisFields.CALL_HISTORY_CALL_TASK_ID).toString(); //
                    packageId        = json.get(RedisFields.CALL_HISTORY_CALL_PACKAGE_ID)         == null?null:json.get(RedisFields.CALL_HISTORY_CALL_PACKAGE_ID).toString(); //
                    actionCodeBreak        = json.get(RedisFields.CALL_HISTORY_CALL_ACTION_CODE_BREAK)         == null?null:json.get(RedisFields.CALL_HISTORY_CALL_ACTION_CODE_BREAK).toString(); //
                    voiceCode        = json.get(RedisFields.CALL_HISTORY_CALL_VOICE_CODE)         == null?null:json.get(RedisFields.CALL_HISTORY_CALL_VOICE_CODE).toString(); //
                    voiceText        = json.get(RedisFields.CALL_HISTORY_CALL_VOICE_TEXT)         == null?null:json.get(RedisFields.CALL_HISTORY_CALL_VOICE_TEXT).toString(); //
                    company        = json.get(RedisFields.CALL_HISTORY_COMPANY)         == null?null:json.get(RedisFields.CALL_HISTORY_COMPANY).toString(); //

                    /**没有sessionId自动生产*/
                    if(StringUtil.isEmpty(sessionId)){
                        sessionId = UUIDs.base64UUID();
                    }
                    //先验证基本参数合法
                    validateMap = validateAsrClickCallWebSocket(mainCallPhone, targetCallPhone, token,userId, dataId, whereFrom,
                            pageFrom, mainCallType, commitTo,customerName,sessionId,actionCodeBreak,voiceCode,voiceText);
                    //有异常通知客户端
                    if(validateMap!=null){
                        SpringWebSocketUtils.pushToClient(session,JSONObject.toJSONString(validateMap));
                        return;
                    }

                    SampleCache.sessionIdTokenMap.put(sessionId,token);

                    switch (commitTo) {
                        case "13"://fs单呼
                            validateMap = freeswitchAsrCallService.handleClickCallWebSocket(mainCallPhone, token,
                                    String.valueOf(userId),userNo,String.valueOf(dataId), String.valueOf(whereFrom),
                                    String.valueOf(pageFrom), String.valueOf(mainCallType), String.valueOf(commitTo),
                                    city, customerName, showNum,project,propertyNo,objectId,sessionId,callTaskId,packageId,packageName,voiceCode,voiceText);
                            break;
                        default:
                            validateMap = aliyunCallService.handleAsrClickCallWebSocket(mainCallPhone, targetCallPhone, token,
                                    String.valueOf(userId), String.valueOf(dataId), String.valueOf(whereFrom),
                                    String.valueOf(pageFrom), String.valueOf(mainCallType), String.valueOf(commitTo),
                                    city, customerName, showNum,project,propertyNo,objectId,sessionId,callTaskId,packageId,actionCodeBreak,voiceCode,voiceText,company);
                    }
                    if(validateMap!=null){//有异常通知客户端
                        SpringWebSocketUtils.pushToClient(session,JSONObject.toJSONString(validateMap));
                    }
                    break;
                //双呼
                case "asrCall2":
                    needAsr = true;
                case "CALL": //外呼消息

                    logger.info("received message:{}",message.getPayload().toString());
                    sessionId       = json.get(RedisFields.CALL_HISTORY_SESSION_ID)       == null?null:json.get(RedisFields.CALL_HISTORY_SESSION_ID).toString(); //
                    mainCallPhone   = json.get(RedisFields.CALL_HISTORY_MAIN_CALL_PHONE)   == null?null:json.get(RedisFields.CALL_HISTORY_MAIN_CALL_PHONE).toString().trim(); //主叫；由拨号时发送过来
                    targetCallPhone = json.get(RedisFields.CALL_HISTORY_TARGET_CALL_PHONE) == null?null:json.get(RedisFields.CALL_HISTORY_TARGET_CALL_PHONE).toString().trim(); //被叫；由拨号时发送过来
                    token           = json.get(RedisFields.CALL_HISTORY_MACHINE_FROM)      == null?null:json.get(RedisFields.CALL_HISTORY_MACHINE_FROM).toString();//机器码：用于定位websocket对象（websocket）
                    userId          = json.get(RedisFields.CREATE_USER_ID)                 == null?null:json.get(RedisFields.CREATE_USER_ID).toString();
                    userNo          = json.get(RedisFields.CREATE_USER_NO)                 == null?null:json.get(RedisFields.CREATE_USER_NO).toString();
                    dataId          = json.get(RedisFields.CALL_HISTORY_DATA_ID)           == null?null:json.get(RedisFields.CALL_HISTORY_DATA_ID).toString(); //置业或app数据库 数据id，用于jms推送数据时，置业或app更新数据的索引；这要求置业或app保存数据成功后再提交呼叫任务到云呼
                    whereFrom       = json.get(RedisFields.CALL_HISTORY_WHERE_FROM)        == null?null:json.get(RedisFields.CALL_HISTORY_WHERE_FROM).toString(); //来源：app(0),置业(1)
                    pageFrom        = json.get(RedisFields.CALL_HISTORY_PAGE_FROM)         == null?null:json.get(RedisFields.CALL_HISTORY_PAGE_FROM).toString(); //app盘源(0),app联动call(1),置业盘源(2)，置业联动call(3)? （websocket）
                    mainCallType    = json.get(RedisFields.CALL_HISTORY_MAIN_CALL_TYPE)    == null?null:json.get(RedisFields.CALL_HISTORY_MAIN_CALL_TYPE).toString(); //主叫号码是什么号码
                    commitTo        = json.get(RedisFields.CALL_HISTORY_COMMIT_TO)         == null?null:json.get(RedisFields.CALL_HISTORY_COMMIT_TO).toString(); //提交到哪里：东进(0)/电信(1)/手机(2)
                    city            = json.get(RedisFields.CALL_HISTORY_CITY)              == null?null:json.get(RedisFields.CALL_HISTORY_CITY).toString();   //经纪所在的城市
                    customerName    = json.get(RedisFields.CALL_HISTORY_CUSTOMER_NAME)     == null?null:json.get(RedisFields.CALL_HISTORY_CUSTOMER_NAME).toString(); //
                    showNum         = json.get(RedisFields.CALL_HISTORY_SHOW_NUM)          == null?null:json.get(RedisFields.CALL_HISTORY_SHOW_NUM).toString(); //
                    project         = json.get(RedisFields.CALL_HISTORY_PROJECT)           == null?null:json.get(RedisFields.CALL_HISTORY_PROJECT).toString(); //
                    propertyNo      = json.get(RedisFields.CALL_HISTORY_PROPERTY_NO)       == null?null:json.get(RedisFields.CALL_HISTORY_PROPERTY_NO).toString(); //
                    objectId        = json.get(RedisFields.CALL_HISTORY_OBJECT_ID)         == null?null:json.get(RedisFields.CALL_HISTORY_OBJECT_ID).toString(); //
                    callTaskId        = json.get(RedisFields.CALL_HISTORY_CALL_TASK_ID)         == null?null:json.get(RedisFields.CALL_HISTORY_CALL_TASK_ID).toString(); //
                    packageId        = json.get(RedisFields.CALL_HISTORY_CALL_PACKAGE_ID)         == null?null:json.get(RedisFields.CALL_HISTORY_CALL_PACKAGE_ID).toString(); //
                    packageName    = json.get(RedisFields.CALL_HISTORY_CALL_PACKAGE_NAME)== null?null:json.get(RedisFields.CALL_HISTORY_CALL_PACKAGE_NAME).toString();
                    source        = json.get(RedisFields.SOURCE)         == null?null:json.get(RedisFields.SOURCE).toString(); //
                    company        = json.get(RedisFields.CALL_HISTORY_COMPANY)         == null?null:json.get(RedisFields.CALL_HISTORY_COMPANY).toString();

                    /**没有sessionId自动生产*/
                    if(StringUtil.isEmpty(sessionId)){
                        sessionId = UUIDs.base64UUID();
                    }
                    //由于存在保利外网链接的情况，所以外呼的时候加个source来源用于判断是否一定是保利调用的呼出
                    if(!"aiCall".equals(source)) {
                        if (source == null || !source.equals("bl") || !whereFrom.equals("11")){
                            validateMap = new HashMap<>();
                            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
                            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DESC, Constants.LOCAL_EXCEPTION_20);
                            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));
                            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_SESSION_ID, sessionId);
                            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DATA_ID, dataId);
                            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_PAGE_FROM, pageFrom);
                            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_WHERE_FROM, whereFrom);
                            SpringWebSocketUtils.pushToClient(session,JSONObject.toJSONString(validateMap));
                            return;
                        }

                    }

                    //先验证基本参数合法
                    validateMap = validateClickCallWebSocket(mainCallPhone, targetCallPhone, token,userId, dataId, whereFrom,
                            pageFrom, mainCallType, commitTo,customerName,sessionId);

                    //有异常通知客户端
                    if(validateMap!=null){
                        SpringWebSocketUtils.pushToClient(session,JSONObject.toJSONString(validateMap));
                        return;
                    }

                    SampleCache.sessionIdTokenMap.put(sessionId,token);

                    /**RPC调用*/
                    switch (commitTo) {
                        //阿里云线路
                        case "0":
                        case "1":
                        case "9":   //旧版云呼阿里云线路
                        case "10":  //智能云呼阿里云线路
                        case "11":  //保利测试阿里云线路
                            validateMap = aliyunCallService.handleClickCallWebSocket(mainCallPhone, targetCallPhone, token,
                                    String.valueOf(userId), String.valueOf(dataId), String.valueOf(whereFrom),
                                    String.valueOf(pageFrom), String.valueOf(mainCallType), String.valueOf(commitTo),
                                    city, customerName, showNum,project,propertyNo,objectId,sessionId,callTaskId,packageId);
                            break;
                        case "8": //fs插卡设备呼出线路
                        case "4": //fs联通cop线路
                        case "5": //fs阿里云线路
                            validateMap = freeswitchCallService.handleClickCallWebSocket(mainCallPhone, targetCallPhone, token,
                                    String.valueOf(userId),userNo,String.valueOf(dataId), String.valueOf(whereFrom),
                                    String.valueOf(pageFrom), String.valueOf(mainCallType), String.valueOf(commitTo),
                                    city, customerName, showNum,project,propertyNo,objectId,sessionId,callTaskId,packageId,packageName,needAsr,company);
                            break;
                        case "2":
                            //使用手机外呼：commitTo=2

                            String isTest= Constants.FALSE;
                            if(WebSocketManager.checkIsTest(session)){
                                isTest=Constants.TRUE;
                                logger.info("browser webSocket id:{},is test,old userId:{}",session.getId(),userId);
                                userId = WebSocketManager.createTestUserId(userId);//0000+userId
                                logger.info("browser webSocket id:{},is test,new userId:{}",session.getId(),userId);
                            }

                            /*检测app是否已连接云呼*/
                            WebSocketSession session1 = WebSocketManager.appHasConnected(userId);
                            if(session1 != null){

                                mainCallPhone = String.valueOf(session1.getAttributes().get("mianCallPhone"));
                                //RPC调用
                                //生成sessionId,外呼任务初步入redis,发送外呼任务到手机app
                                /*validateMap = clickCallToAppService.handleCallWithPhone(mainCallPhone, targetCallPhone, token,
                                        userId, String.valueOf(dataId), String.valueOf(whereFrom),
                                        String.valueOf(pageFrom), String.valueOf(mainCallType), "2", city,
                                        customerName, showNum,project,propertyNo,objectId,isTest,sessionId);*/

                            }else {

                                validateMap = new HashMap<>(6);
                                validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
                                validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DESC, Constants.LOCAL_EXCEPTION_APP_NO_LOGIN);
                                validateMap.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));
                                validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DATA_ID, dataId);
                                validateMap.put(Constants.WEB_SOCKET_JSON_KEY_SESSION_ID, sessionId);
                                validateMap.put(Constants.WEB_SOCKET_JSON_KEY_PAGE_FROM, pageFrom);
                                validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MACHINE_FROM, token);

                            }
                            break;
                        default:
                            validateMap = aliyunCallService.handleClickCallWebSocket(mainCallPhone, targetCallPhone, token,
                                    String.valueOf(userId), String.valueOf(dataId), String.valueOf(whereFrom),
                                    String.valueOf(pageFrom), String.valueOf(mainCallType), String.valueOf(commitTo),
                                    city, customerName, showNum,project,propertyNo,objectId,sessionId,callTaskId,packageId);
                            break;
                    }

                    if(validateMap!=null){//有异常通知客户端
                        SpringWebSocketUtils.pushToClient(session,JSONObject.toJSONString(validateMap));
                    }

                    mainCallPhone = null;
                    targetCallPhone = null;
                    token = null;
                    userId = null;
                    dataId = null;
                    whereFrom = null;
                    pageFrom = null;
                    mainCallType = null;
                    commitTo = null;
                    customerName = null;
                    break;
                case "VOICE": //语音消息
                    String pId = null;
                    sessionId = json.get(RedisFields.CALL_HISTORY_SESSION_ID) == null ? null : json.get(RedisFields.CALL_HISTORY_SESSION_ID).toString();
                    pId = json.get("pId") == null ? null : json.get("pId").toString();
                    if(PublicConfig.isOpenVoiceRecognise && sessionId != null && pId != null && !"".equals(pId)) {
                        /**RPC调用*/
//                        voiceRecognizerService.startRecognition(sessionId, pId);
                    }
                    break;
                case "CANCEL": //取消消息
                    break;
                case "changePc"://切换电脑进行外呼
                    //1、发送notNeedReconnect消息到上一台电脑的所有websocket连接上，通知客户端不需要重连

                    token     = json.get("token")  == null?null:json.get("token").toString();//机器码：用于定位websocket对象（websocket）
                    userId    = json.get("userId") == null?null:json.get("userId").toString();

                    if(WebSocketManager.checkIsTest(session)){
                        logger.info("browser webSocket id:{},is test,old userId:{}",session.getId(),userId);
                        userId = WebSocketManager.createTestUserId(userId);//0000+userId
                        logger.info("browser webSocket id:{},is test,new userId:{}",session.getId(),userId);
                    }

                    if(StringUtil.isEmpty(token) || StringUtil.isEmpty(userId)){
                        map = new HashMap<>();

                        map.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
                        map.put(Constants.WEB_SOCKET_JSON_KEY_CODE, Constants.FAIL);
                        map.put(Constants.WEB_SOCKET_JSON_KEY_DESC, "机器码或用户ID不能为空");
                        map.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));

                        SpringWebSocketUtils.pushToClient(session, JSONObject.toJSONString(map));
                        return;
                    }

                    String currentMachineId = null;
                    int index_ = token.indexOf("_");

                    if(index_ == -1){
                        map = new HashMap<>();

                        map.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
                        map.put(Constants.WEB_SOCKET_JSON_KEY_CODE, Constants.FAIL_2);
                        map.put(Constants.WEB_SOCKET_JSON_KEY_DESC, "机器码异常");
                        map.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));

                        SpringWebSocketUtils.pushToClient(session, JSONObject.toJSONString(map));
                        return;
                    }

                    currentMachineId = token.substring(0,index_);

                    Map<String, List<WebSocketSession>> machineWebSocketListMap = WebSocketManager.getBrowserUserMahineWebSocketSessionsMap().get(userId);

                    if(machineWebSocketListMap == null) {
                        logger.info("zyUserId:{},exception,no websocket at all.", userId);
                        machineWebSocketListMap = new HashMap<>();
                    }

                    String returndesc = null;
                    //关闭其他电脑的连接，并通知客户端不重连
                    logger.info("before changePc,连接情况:{}",WebSocketManager.getBrowserMachineSessionSizeDesc(userId));

                    for(Map.Entry<String, List<WebSocketSession>> entry:machineWebSocketListMap.entrySet()){

                        if(!currentMachineId.equals(entry.getKey())) { //只关闭切换后的电脑之外的连接
                            logger.info("machineId:{},sessionSize:{}",entry.getKey(),entry.getValue().size());
                            if (entry.getValue().size() > 0) {
                                String closedesc = "切换电脑，关闭该电脑所有连接，不需重连" + "该电脑机器ID:" + entry.getKey() + "连接数:" + entry.getValue().size();
                                map = new HashMap<>();
                                int sendCount = 0;

                                for (WebSocketSession socketSession : entry.getValue()) {
                                    logger.info("closing session,token:{}",session.getAttributes().get("token"));
                                    map.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_NOT_RE_WEBSOCKET);
                                    map.put(Constants.WEB_SOCKET_JSON_KEY_CODE, Constants.FAIL);
                                    map.put(Constants.WEB_SOCKET_JSON_KEY_DESC, closedesc);
                                    map.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));
                                    /**每个连接都通知，不重连*/
                                    //关闭连接
                                    logger.info("closing session,session is open:{}",socketSession.isOpen());
                                    if(socketSession.isOpen()) {

                                        logger.info("通知不需重连：msg:{}",JSONObject.toJSONString(map));
                                        SpringWebSocketUtils.pushToClient(socketSession, JSONObject.toJSONString(map));
                                        logger.info("通知不需重连over");
                                        socketSession.close();
                                    }

                                    map.clear();
                                    sendCount++;
                                }
                                logger.info("关闭上台电脑连接，并通知客户端不重连:zyUserId:{},token:{},处理连接数:{}", userId, token, sendCount);
                            }
                        }
                    }

                    returndesc = "切换成功";

                    //保存连接
                    WebSocketManager.browserTokenWebSocketSessionMap.put(token,session);
                    WebSocketManager.addBrowserUserMachineWebSocketSession(userId,currentMachineId,session);
                    WebSocketManager.browserUserTokenWebSocketSessionMap.put(userId+token,session);

                    map = new HashMap<>();

                    map.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_WEBSOCKET_CHANGE_PC);
                    map.put(Constants.WEB_SOCKET_JSON_KEY_CODE, Constants.SUCCESS_1);
                    map.put(Constants.WEB_SOCKET_JSON_KEY_DESC, returndesc);
                    map.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));

                    SpringWebSocketUtils.pushToClient(session, JSONObject.toJSONString(map));

                    logger.info("通知完成,当前连接信息:{},zyUserId:{},token:{}",
                            WebSocketManager.getBrowserMachineSessionSizeDesc(userId),userId,token);

                    break;
                case "notChangePc"://不切换
                    //1、发送notNeedReconnect消息到该电脑的websocket连接上，通知客户端不需要重连
                    map  = new HashMap<>();

                    map.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_NOT_RE_WEBSOCKET);
                    map.put(Constants.WEB_SOCKET_JSON_KEY_CODE, Constants.FAIL);
                    map.put(Constants.WEB_SOCKET_JSON_KEY_DESC, "不切换电脑，将关闭该连接，不需重连");
                    map.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));

                    SpringWebSocketUtils.pushToClient(session, JSONObject.toJSONString(map));

                    //关闭连接
                    if(session.isOpen()) {
                        session.close();
                    }

                    break;
                case "BEAT": //心跳消息
//                    logger.debug("browser webSocket heat beat");
                    break;
                case "CRMHEARTBEAT": //心跳消息
                    logger.info("crm的freeswitch心跳,时间:"+json.get("timestamp").toString());
                    Map<String,String> messageMap=new HashMap();
                    messageMap.put("msgType","I'm still alive");
                    messageMap.put("desc","心跳回应信息,服务器正常");
                    SpringWebSocketUtils.pushToClient(session, JSONObject.toJSONString(messageMap));
                    break;

                default:
                    logger.error("received error msgType from client");
                    break;
            }

        } catch (Exception e) {

            validateMap = new HashMap<>();
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DESC,Constants.LOCAL_EXCEPTION_DEAL_BROWSER_MSG);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_USER_ID, userId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MACHINE_FROM, token);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DATA_ID, dataId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_SESSION_ID, sessionId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));

            SpringWebSocketUtils.pushToClient(session, JSONObject.toJSONString(validateMap));
            e.printStackTrace();
            logger.error("webSocket handle message exception! stace:{}",e);
        }
    }


    /**
     * 验证参数合法
     * @machineFrom token
     * @return 正常情况下：返回null
     * */
    public Map<String,String> validateClickCallWebSocket( String mainCallPhone,String targetCallPhone ,String machineFrom ,
                                                          String createUserId ,String dataId  ,String whereFrom ,String pageFrom ,
                                                          String mainCallType ,String commitTo ,String customerName,String sessionId ) {

        Map<String, String> validateMap = null;

        if( mainCallPhone == null || //主叫；由拨号时发送过来
                targetCallPhone == null || //被叫；由拨号时发送过来
                machineFrom == null ||//机器码：用于定位websocket对象（websocket）
   //             createUserId == null ||
//            sessionId == null ||
//            dataId == null || //置业或app数据库 数据id，用于jms推送数据时，置业或app更新数据的索引；这要求置业或app保存数据成功后再提交呼叫任务到云呼
                whereFrom == null || //来源：app(0),置业(1)
   //             pageFrom == null || //app盘源(0),app联动call(1),置业盘源(2)，置业联动call(3)? （websocket）
//            mainCallType == null || //mainCallPhone是什么号码？经纪人：1/客户：0
                 commitTo == null //提交到哪里：东进(0)/电信(1)
              //  customerName == null
                ){

            validateMap = new HashMap<>(6);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DESC, Constants.LOCAL_EXCEPTION_4);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_SESSION_ID, sessionId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DATA_ID, dataId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_PAGE_FROM, pageFrom);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MACHINE_FROM, machineFrom);

            return validateMap;
        }

//        if (!ValidateUtils.isNumeric(mainCallPhone) ||
               if( !ValidateUtils.isNumeric(targetCallPhone)) {

            validateMap = new HashMap<>(6);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DESC, Constants.LOCAL_EXCEPTION_2_2);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_SESSION_ID, sessionId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DATA_ID, dataId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_PAGE_FROM, pageFrom);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MACHINE_FROM, machineFrom);

            return validateMap;
        }

        if (!ValidateUtils.isNumeric(whereFrom) ||
                !ValidateUtils.isNumeric(mainCallType)) {

            validateMap = new HashMap<>(6);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DESC, Constants.LOCAL_EXCEPTION_2);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_SESSION_ID, sessionId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DATA_ID, dataId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_PAGE_FROM, pageFrom);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MACHINE_FROM, machineFrom);

            return validateMap;
        }

        if (mainCallPhone.equals(targetCallPhone) && !pageFrom.equals("5")) { //拦截主叫被叫相同的；测试座机页面允许
            validateMap = new HashMap<>(6);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DESC, Constants.LOCAL_EXCEPTION_5);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_SESSION_ID, sessionId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DATA_ID, dataId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_PAGE_FROM, pageFrom);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MACHINE_FROM, machineFrom);

            return validateMap;
        }
        return validateMap;
    }


    /**
     * 验证参数合法 asr 智能外呼
     * @machineFrom token
     * @return 正常情况下：返回null
     * */
    public Map<String,String> validateAsrClickCallWebSocket( String mainCallPhone,String targetCallPhone ,String machineFrom ,
                                                          String createUserId ,String dataId  ,String whereFrom ,String pageFrom ,
                                                          String mainCallType ,String commitTo ,String customerName,String sessionId,String actionCodeBreak,String voiceCode,String voiceText) {

        Map<String, String> validateMap = null;

        //必须有开场录音

        if( mainCallPhone == null||
                machineFrom == null ||//机器码：用于定位websocket对象（websocket）
                whereFrom == null || //来源：app(0),置业(1)
                commitTo == null //提交到哪里：东进(0)/电信(1)
                || actionCodeBreak ==null||(voiceCode==null&&voiceText==null)
                ){

            validateMap = new HashMap<>(6);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DESC, Constants.LOCAL_EXCEPTION_4);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_SESSION_ID, sessionId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DATA_ID, dataId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_PAGE_FROM, pageFrom);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MACHINE_FROM, machineFrom);

            return validateMap;
        }

        if (!ValidateUtils.isNumeric(mainCallPhone) ) {

            validateMap = new HashMap<>(6);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DESC, Constants.LOCAL_EXCEPTION_2_2);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_SESSION_ID, sessionId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DATA_ID, dataId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_PAGE_FROM, pageFrom);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MACHINE_FROM, machineFrom);

            return validateMap;
        }

        if (!ValidateUtils.isNumeric(createUserId) ||
                !ValidateUtils.isNumeric(whereFrom) ||
                !ValidateUtils.isNumeric(pageFrom) ||
                !ValidateUtils.isNumeric(mainCallType)) {

            validateMap = new HashMap<>(6);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE, Constants.WEB_SOCKET_MSG_TYPE_EXCEPTION);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DESC, Constants.LOCAL_EXCEPTION_2);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_TIME, DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS));
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_SESSION_ID, sessionId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_DATA_ID, dataId);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_PAGE_FROM, pageFrom);
            validateMap.put(Constants.WEB_SOCKET_JSON_KEY_MACHINE_FROM, machineFrom);

            return validateMap;
        }
        return validateMap;
    }

}
